﻿using System;
using System.Text;
using System.Diagnostics;
using System.Management;
using System.Globalization;
using System.Threading;
using System.Text.RegularExpressions;
using System.Reflection;


namespace freedisk
{
    class Program
    {

        static void Main(string[] args)
        {

            
            string selectString = "SELECT * FROM Win32_LogicalDisk";
            string machineToCheck = ".";
            bool showColumns = true;

            for (int i = 0; i < args.Length; i++)
            {
                switch (args[i])
                {
                    case "-d":
                        {
                            if (args.Length > i + 1)
                            {
                                i++;
                                string inputString = RemoveInvalidChars(args[i]);
                                selectString += " WHERE Name = '" + inputString + "'";
                            }
                            break;
                        }
                    case "-b":
                        {
                            showColumns = false;
                            break;
                        }
                    case "-m":
                        {
                            if (args.Length > i + 1)
                            {
                                i++;
                                machineToCheck = RemoveInvalidChars(args[i]);
                            }
                            break;
                        }
                    case "-?":
                    //fall through to default
                    default:
                        ShowUsage();
                        return;
                }
            }

            try
            {

                ManagementScope scope = new ManagementScope("\\\\" + machineToCheck + "\\root\\cimv2");
                SelectQuery select = new SelectQuery(selectString);
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, select);

                Console.WriteLine("");

                if (showColumns)
                {
                    Console.WriteLine("Name Size (GB)   Free (GB)");
                    Console.WriteLine("---- ---------   --------");
                }

                foreach (ManagementObject disk in searcher.Get())
                {
                    UInt64 size = Convert.ToUInt64(disk.GetPropertyValue("Size"));
                    UInt64 free = Convert.ToUInt64(disk.GetPropertyValue("FreeSpace"));
                    if (size > 0)
                        Console.WriteLine("{0}   {1}    {2}", disk.GetPropertyValue("Name"), BytesToFormattedGB(size, 8), BytesToFormattedGB(free, 8));
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception: " + ex.Message);

            }
        }

        private static string BytesToFormattedGB(UInt64 bytes, int padding)
        {
            return BytesToFormattedGB(bytes).PadLeft(padding, '0');
        }

        private static string BytesToFormattedGB(UInt64 bytes)
        {

            UInt64 divisor = 1024 * 1024 * 1024;
            float megaBytes = (float)bytes / (float)divisor;
            return Convert.ToString(megaBytes.ToString("G", Thread.CurrentThread.CurrentCulture));
        }

        private static string RemoveInvalidChars(string inputString) {


            string pattern = @"\<;-'";
            Regex r = new Regex(pattern);

            return r.Replace(inputString, " ");
        }

        private static void ShowUsage()
        {
            
           
            Console.WriteLine("");

            Assembly asm = Assembly.GetExecutingAssembly();
            if (asm != null)
            {
                AssemblyName asmName = asm.GetName();
                Console.WriteLine("{0}.exe Version {1}", asmName.Name, asmName.Version);
            }
            else {
                Console.WriteLine("freedisk.exe");
            }
            
            Console.WriteLine("USAGE: freedisk.exe [-d driveletter] [-b] [-m computername] [-?]");
            Console.WriteLine("       -d = Drive to check (default is all)");
            Console.WriteLine("       -b = Do not display headings");
            Console.WriteLine("       -m = Computer to check (default is .)");
            Console.WriteLine("       -? = Shows this help");
            Console.WriteLine("");
        }


    }
}
